/**
 * Copyright (c) 2012-2017, www.tinygroup.org (luo_guo@icloud.com).
 * <p>
 * Licensed under the GPL, Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/gpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.tinygroup.springwithtemplate3.impl;

import org.apache.commons.lang.StringUtils;
import org.springframework.web.servlet.view.AbstractTemplateView;
import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.commons.i18n.LocaleUtil;
import org.tinygroup.config.util.ConfigurationUtil;
import org.tinygroup.context.impl.ContextImpl;
import org.tinygroup.logger.LogLevel;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import org.tinygroup.springwithtemplate3.ServletContextUtil;
import org.tinygroup.template.TemplateContext;
import org.tinygroup.template.TemplateEngine;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;

/**
 * tiny模板类的view对象
 *
 * @author renhui
 */
public class TinyTemplateLayoutView extends AbstractTemplateView {

    private static final String VIEW_EXT_FILENAME = "page";// 视图扩展名
    private static final String PAGELET_EXT_FILE_NAME = "pagelet";
    private static final Logger logger = LoggerFactory
            .getLogger(TinyTemplateLayoutView.class);
    private TemplateEngine templateEngine;
    private String viewExtFileName = VIEW_EXT_FILENAME;
    private String noLayoutExtFileName = PAGELET_EXT_FILE_NAME;

    public TemplateEngine getTemplateEngine() {
        return templateEngine;
    }

    public void setTemplateEngine(TemplateEngine templateEngine) {
        this.templateEngine = templateEngine;
    }

    public void setViewExtFileName(String viewExtFileName) {
        this.viewExtFileName = viewExtFileName;
    }

    public void setNoLayoutExtFileName(String noLayoutExtFileName) {
        this.noLayoutExtFileName = noLayoutExtFileName;
    }

    @Override
    protected void renderMergedTemplateModel(Map<String, Object> model,
                                             HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        long startTime = System.currentTimeMillis();
        response.setContentType(getContentType());
        //model.put("uiengine",getApplicationContext().getBean("uiComponentManager"));
        TemplateContext templateContext = createTemplateContext(model, request,
                response);
        String path = getUrl();
        String extFileName = getExtFileName(path);
        if (isPagelet(path)) {
            templateEngine.renderTemplateWithOutLayout(extFileName,
                    templateContext, response.getOutputStream());
        } else {
            templateEngine.renderTemplate(extFileName, templateContext,
                    response.getOutputStream());
        }
        logger.logMessage(LogLevel.DEBUG, "路径<{}>处理时间：{}ms", path,
                System.currentTimeMillis() - startTime);
    }

    private TemplateContext createTemplateContext(Map<String, Object> model, HttpServletRequest request,
                                                  HttpServletResponse response) {
        TemplateContext templateContext = new SpringTemplateContext(model, request);
        templateContext.put(
                "uiengine",
                BeanContainerFactory.getBeanContainer(
                        this.getClass().getClassLoader()).getBean(
                        "uiComponentManager"));
        templateContext.putSubContext("applicationproperties", new ContextImpl(
                ConfigurationUtil.getConfigurationManager()
                        .getConfiguration()));

        // 设置templateContext的内置对象
        templateContext.put("request", request);
        templateContext.put("response", response);
        templateContext.put("session", request.getSession());
        templateContext.put("application",
                ServletContextUtil.getServletContext());
        templateContext.put("defaultLocale", LocaleUtil.getContext()
                .getLocale());

        templateContext.put("TINY_CONTEXT_PATH", request.getContextPath());
        templateContext.put("TINY_REQUEST_URI", request.getRequestURI());

        return templateContext;
    }

    public boolean checkResource(Locale locale) throws Exception {
        String path = getExtFileName(getUrl());
        try {
            return templateEngine.findTemplate(path) != null;
        } catch (Exception e) {
            logger.logMessage(LogLevel.DEBUG,
                    "Could not load tiny template for URL [{0}]", path);
        }
        return false;
    }

    private boolean isPagelet(String path) {
        return StringUtils.endsWith(path, noLayoutExtFileName);
    }

    private String getExtFileName(String path) {
        if (isPagelet(path)) {
            return StringUtils.substringBeforeLast(path, noLayoutExtFileName)
                    + viewExtFileName;
        }
        return path;
    }

    // 不设置字符集编码，由过滤器进行设置
    protected void applyContentType(HttpServletResponse response) {

    }

}
